package com.ruike.alisurface.Serials;

import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;

import com.voodoo.lib_utils.ByteUtils;
import com.voodoo.lib_utils.L;

/**
 * Author: voodoo
 * CreateDate: 2023/09/26 026 上午 11:39
 * Description: 反扫
 */
public class ReScanUtils {

    static Handler mainHandler;
    // 是否需要回调结果
    public static boolean isCanCallbackResult = false;
    // 返回数据监听
    static OnReScanListener mOnReScanListener;

    public static void initListener() {
        mainHandler = new Handler(Looper.getMainLooper());
        Ttys1Utils.getInstance().setOnSerialPortResultDataListener((resultDataStr, resultBytes) -> {
            if (!TextUtils.isEmpty(resultDataStr) && resultBytes != null && resultBytes.length > 0) {
                mySerialPortResultData(resultDataStr, resultBytes);
            } else {
                L.e("返回指令异常");
            }
        });
    }

    static StringBuffer resultByteSb;

    private static void mySerialPortResultData(String serialPortData, byte[] resultBytes) {

        // 指令操作返回值
        if (resultBytes[0] == 0x02 && resultBytes[1] == 0x00) {
            if (resultBytes[2] == 0x00) {
                L.i("操作成功");
            }
            return;
        }

        if (!isCanCallbackResult) {
            L.i("非启用阶段，不处理");
//            if (mOnReScanListener != null) {
//                mainHandler.post(new Runnable() {
//                    @Override
//                    public void run() {
//                        mOnReScanListener.onReScanResultListener(false, "非反扫阶段，不处理");
//                    }
//                });
//            }
            return;
        }

        if (resultByteSb == null) {
            resultByteSb = new StringBuffer();
        }
        // 如果之前品结果，在之前的指令结尾加个空格
        if (resultByteSb.length() > 0) {
            resultByteSb.append(" ");
        }
        resultByteSb.append(serialPortData);
        if (!serialPortData.endsWith("0D")) {
            L.e("结尾非 0x0D，数据不全，继续等待...");
            return;
        }

        String resultByteStr = resultByteSb.toString();
        resultByteSb = null;
        L.i("回传尾字节数组，整体回传：" + resultByteStr);

        byteArrayToString(resultByteStr);

    }

    /**
     * 将完整的串口返回数据转换成字符串
     *
     * @param byteStr 待转换的串口数据
     */
    static void byteArrayToString(String byteStr) {
        stopReadQrCode();
        byteStr = byteStr.replace(" ", "");
        byte[] resultBytes = ByteUtils.hexToByteArr(byteStr);
        char[] chars = new char[resultBytes.length];
        for (int i = 0; i < resultBytes.length; i++) {
            chars[i] = (char) Integer.parseInt(ByteUtils.byteToHex(resultBytes[i]), 16);
        }
        String resultStr = String.valueOf(chars);
        L.i("转换后的结果：" + String.valueOf(chars));
        // 对数据结果进行回调
        if (mOnReScanListener != null) {
            mainHandler.post(() -> {
                L.i("扫码结果回调出去");
                mOnReScanListener.onReScanResultListener(true, resultStr);
            });
            return;
        }
        L.i("扫码结果无回调，监听为空");
    }

    /**
     * 开始读取数据
     */
    public static void startReadQrCode() {
        isCanCallbackResult = true;
    }

    /**
     * 结束读取
     */
    public static void stopReadQrCode() {
        isCanCallbackResult = false;
    }

    /**
     * 复位
     */
    public static void reset() {
        byte[] sendBytes = new byte[7];
        int index = 0;
        sendBytes[index++] = 0x7E; // {Head1}
        sendBytes[index++] = 0x00; // {Head1}
        sendBytes[index++] = 0x09; // {Types} 07读  08写
        sendBytes[index++] = 0x01; // {Lens}
        sendBytes[index++] = 0x00; // {Address}
        sendBytes[index++] = 0x00; // {Address}
        sendBytes[index] = (byte) 0xFF; // {Datas}
        String sendByteStr = ByteUtils.byteArrToHex(getCrcCcitt(sendBytes, 2));
        L.i("发送反扫器复位指令：" + sendByteStr);
        Ttys1Utils.getInstance().SendPort(sendByteStr);
    }

    /**
     * 获取 CRC-CCITT 校验值
     *
     * @param bytes      待计算的 byte 数组
     * @param startIndex 计算起始下标，大于等于0，则按照下标计算，否则按照协议中的不计算去处理
     * @return 带校验位的 byte 数组
     */
    private static byte[] getCrcCcitt(byte[] bytes, int startIndex) {
        if (bytes == null || bytes.length <= 0) {
            return bytes;
        }

        byte heightByte = (byte) 0xAB;
        byte lowByte = (byte) 0xBC;

        if (startIndex >= 0) {
            if (startIndex > bytes.length - 1) {
                return bytes;
            }
            byte[] tempBytes = new byte[bytes.length - startIndex];
            System.arraycopy(bytes, startIndex, tempBytes, 0, tempBytes.length);
            byte[] toByteArr = CRC_XModem(tempBytes);
            heightByte = toByteArr[0];
            lowByte = toByteArr[1];
        }

        byte[] resultBytes = new byte[bytes.length + 2];
        System.arraycopy(bytes, 0, resultBytes, 0, bytes.length);
        resultBytes[resultBytes.length - 2] = heightByte;
        resultBytes[resultBytes.length - 1] = lowByte;
        return resultBytes;
    }

    /**
     * CRC16-CCITT(XModem)
     *
     * @param bytes 待计算校验值的字节数组
     * @return 计算完成之后的值
     */
    public static byte[] CRC_XModem(byte[] bytes) {
        int crc = 0x00;
        int polynomial = 0x1021;
        for (int index = 0; index < bytes.length; index++) {
            byte b = bytes[index];
            for (int i = 0; i < 8; i++) {
                boolean bit = ((b >> (7 - i) & 1) == 1);
                boolean c15 = ((crc >> 15 & 1) == 1);
                crc <<= 1;
                if (c15 ^ bit) crc ^= polynomial;
            }
        }
        crc &= 0xffff;
        return ByteUtils.hexToByteArr(Integer.toHexString(crc).toUpperCase());
    }

    public static void setOnReScanListener(OnReScanListener onReScanListener) {
        mOnReScanListener = onReScanListener;
    }

    public interface OnReScanListener {
        /**
         * 扫描返回结果监听
         *
         * @param isSuccess 是否正确，如果不正确，那么第二个参数为错误原因
         * @param content   返回结果字符串
         */
        void onReScanResultListener(boolean isSuccess, String content);
    }

}
